home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-01 | 25.2 KB | 1,092 lines |
- /*
-
- Copyright 1992, Stefanos Kiakas. All rights reserved.
-
- You may not delete this notice.
-
- */
- #define ABS(x) ( x < 0 ? -x : x) /* macro to calculate absolute value */
- #define RANDTARGET ( random() % TARGETS)/* select a random target to attack */
- #define RANDLAUNCH ( ( random() % 440 ) + 20 ) /* x pos. of attack missles */
- #define PLACECITY(x) ( random() % x ) /* selct position to place city */
-
-
- #define NULL 0 /* define end of list marker */
-
-
- #define MAXRADIUS 15.0 /* maximum radius of explosions */
- #define TERRAINCOLOUR 0.20
-
- #define TIMEINTERVAL 0.1
- #define DELTA_TIME 100
- #define RADINC 1.0 /* radius increment of explosion circles */
- #define MAXDEFEXP 15
- #define MAXDEFLAUNCH 10 /* maximum number of defensive missiles */
- #define MAXATCKMSSLS 10 /* maximum number of attack missiles */
-
- /* define launch coordinates for defensive missiles */
- #define LAUNCH_X 250.0
- #define LAUNCH_Y 25.0
-
- #define DISP 3.0
-
- #define CDX 18.0 // center of target from display coordinates
-
- #define CITYBONUS 500 // city saved bonus
- #define MSLBONUS 50 // missiles saved bonus
- #define MSLDSTRCT 100 // attack missle intercepted ( destroyed ) bonus
- #define BONUSMARK 7000 // give bonus city every so many points
-
- #define OLAUNCH_Y 390.0; /* Y launch position of attack missles */
-
- #define DX 5.0
- #define DY 5.0
-
- #define H_CURSOR 330
- #define W_CURSOR 460
- #define Y_CURSOR 50
- #define X_CURSOR 20
-
- #define H_TRG Y_CURSOR + H_CURSOR
- #define W_TRG X_CURSOR + W_CURSOR
- #define Y_TRG Y_CURSOR
- #define X_TRG X_CURSOR
-
-
- #define MAXNDIFF 2.0 /* maximum difficulty for novice level */
- #define MAXEDIFF 2.5 /* maximum difficulty for experienced level */
- #define MAXPDIFF 3.0 /* maximum difficulty for pro level */
-
-
- #define STARTNDIFF 0.8 /* starting difficulty for novice level */
- #define STARTEDIFF 0.75 /* starting difficulty for experienced level */
- #define STARTPDIFF 0.9 /* starting difficulty for por level */
-
- #define DIFFINCN 0.1 /* increase in difficulty after each attack for novice level */
- #define DIFFINCE 0.25 /* increase in difficulty after each attack for experienced level */
- #define DIFFINCP 0.3 /* increase in difficulty after each attack for pro level */
-
-
- #define DISPLAYDELAY 50000
-
-
- #define SCOREXPOS 150
- #define SCOREYPOS 250
-
- #import "markLoc.h"
- #import "plotTrajectory.h"
- #import "scorePhaseCities.h"
- #import "scorePhaseMissiles.h"
-
- #include <sys/param.h>
- #import <libc.h>
- #import "BattleView.h"
- #import <appkit/appkit.h>
- #import <soundkit/Sound.h>
-
-
-
- @implementation BattleView
-
- - initFrame:(const NXRect *) frm
- {
- char appD[MAXPATHLEN];
- NXPoint mySpot;
-
- [super initFrame:frm ];
-
- [self allocateGState];
-
- gameRunning = FALSE;
- gamePaused = FALSE;
-
- sprintf(appD,"%s/%s",[self appDirectory],"RedAlert.snd");
-
- redAlertSound = [ [Sound alloc] initFromSoundfile:appD ];
-
- cityBitmap = [NXImage findImageNamed:"city3.tiff"];
-
- launcherBitmap = [NXImage findImageNamed:"mBase.tiff"];
-
-
- cursorImage=[NXCursor newFromImage:[NXImage newFromSection:"targetD3.tiff"]];
- cBounds.origin.x = X_CURSOR;
- cBounds.origin.y = Y_CURSOR;
- cBounds.size.width= W_CURSOR;
- cBounds.size.height = H_CURSOR;
-
- mySpot.x = 8;
- mySpot.y = 7;
- [cursorImage setHotSpot:&mySpot];
-
-
- ndiffstart = STARTNDIFF;
- ndiffinc = DIFFINCN;
- ndiffmax = MAXNDIFF;
-
- return self;
- }
-
-
- /*
- This function was shamelessly copied from the examples provided.
-
- */
- - (const char *)appDirectory
- {
- char *suffix;
-
- strcpy(appDirectory, NXArgv[0]);
- if (suffix = rindex(appDirectory,'/'))
- *suffix = '\0';
- if (appDirectory) chdir(appDirectory);
- getwd(appDirectory);
- return appDirectory;
- }
-
- - selectExperienced:sender
- {
- ndiffinc = DIFFINCE;
- ndiffstart = STARTEDIFF;
- ndiffmax = MAXEDIFF;
- return self;
- }
-
- - selectNovice:sender
- {
- ndiffinc = DIFFINCN;
- ndiffstart = STARTNDIFF;
- ndiffmax = MAXNDIFF;
-
- return self;
- }
-
- - selectPro:sender
- {
- ndiffinc = DIFFINCP;
- ndiffstart = STARTPDIFF;
- ndiffmax = MAXPDIFF;
-
- return self;
- }
-
-
- - pauseGame:sender
- {
- void stepFun();
-
- if( gameRunning )
- {
- gameRunning = FALSE;
- gamePaused = TRUE;
- DPSRemoveTimedEntry(gameTimer);
- }
- else if( !gameRunning && gamePaused )
- {
- gameRunning = TRUE;
- gamePaused = FALSE;
- gameTimer =DPSAddTimedEntry(TIMEINTERVAL,&stepFun,self,NX_BASETHRESHOLD);
- }
- return self;
- }
-
- - resetCursorRects
- {
- [self addCursorRect:&cBounds cursor:cursorImage];
- return self;
- }
-
- - newGame:sender
- {
- int i;
- void stepFun();
- unsigned int currentTimeInMs();
- MSLE_NODE_PNTR cpdm,fpdm;
- MA_NODE_PNTR cpam,fpam;
- EXP_PNTR cpe,fpe;
-
- if( !gameRunning && !gamePaused )
- {
- /* set up current game difficulty levels */
- cdiffstart = ndiffstart;
- cdiffinc = ndiffinc;
- cdiffmax = ndiffmax;
-
- dFactor = cdiffstart;
- phaseOne = TRUE;
- defensiveMissiles.launched = 0;
- defensiveMissiles.next = NULL;
-
- offensiveMissiles.launched = 0;
- offensiveMissiles.next = NULL;
-
- defensiveExplosions.exploding = 0;
- defensiveExplosions.next = NULL;
-
- for( i = 0; i < CITIES; i++)
- if( ( i % 3 ) && ( i %4 ) )
- cityStatus[i] = TRUE;
- else
- cityStatus[i] = FALSE;
-
- // reset number of missiles
- aTimeBefore = currentTimeInMs();
-
- // select attack positions
- [self selectTargets];
-
- missiles = 40;
- score = 0;
- lastBonusAt = 0;
- displayBase = TRUE;
-
- [outMissiles setIntValue:missiles];
- [outScore setIntValue:score];
- [window makeKeyAndOrderFront:self];
-
- gameRunning = TRUE;
- gameTimer =DPSAddTimedEntry(TIMEINTERVAL,&stepFun,self,NX_BASETHRESHOLD);
-
- [self display];
- }
- else if( gameRunning && !gamePaused )
- {
- gameRunning = FALSE;
- DPSRemoveTimedEntry(gameTimer);
- // remove entries in linked lists
- cpdm = defensiveMissiles.next;
- while( cpdm != NULL )
- {
- fpdm = cpdm;
- cpdm = cpdm->next;
- free(fpdm);
- }
-
- /* remove attack missiles from list, and free memory */
- cpam = offensiveMissiles.next;
- while( cpdm != NULL )
- {
- fpam = cpam;
- cpam = cpam->next;
- free(fpam);
- }
-
- /* remove air explosions from list and free memory */
- cpe = defensiveExplosions.next;
- while( cpe != NULL )
- {
- fpe = cpe;
- cpe = cpe->next;
- free(fpe);
- }
-
- /* remove surface explosions from list and free memory */
- cpe = surfaceExplosions.next;
- while( cpe != NULL )
- {
- fpe = cpe;
- cpe = cpe->next;
- free(fpe);
- }
-
- }
- return self;
- }
-
-
- unsigned currentTimeInMs()
- {
- struct timeval curTime;
- gettimeofday(&curTime, NULL);
- return ((unsigned)curTime.tv_sec)*1000+curTime.tv_usec / 1000;
- }
-
- - step
- {
- NXEvent dummyEvent;
- unsigned int timeNow,dTime;
-
- do
- {
- timeNow = currentTimeInMs();
- dTime = timeNow - aTimeBefore;
- if( dTime > DELTA_TIME )
- {
- aTimeBefore = timeNow;
-
- if( defensiveMissiles.launched != 0 )
- [self missilePath];
- if( defensiveExplosions.exploding > 0 )
- [self expDraw];
- if( offensiveMissiles.launched > 0)
- [self attackMissilesPath];
- if( surfaceExplosions.exploding > 0 )
- [self surfaceExplosionsDraw];
- }
- if(
- defensiveMissiles.launched == 0 &&
- defensiveExplosions.exploding == 0 &&
- offensiveMissiles.launched == 0 &&
- surfaceExplosions.exploding == 0
- )
- {
- if( !phaseOne )
- [ self bonusPoints];
- [self nextLevel];
- }
- NXPing();
- }
- while ([NXApp peekNextEvent:NX_ALLEVENTS into:&dummyEvent] == NULL );
- return self;
- }
-
- - drawSelf:(const NXRect *)r :(int)c
- {
- int i;
-
- PSsetgray(1.0);
- NXRectFill(r);
- PSsetgray(NX_BLACK);
- NXFrameRect(r);
-
- // draw terrain
- PSsetgray(TERRAINCOLOUR);
- PSnewpath();
-
- PSmoveto(0.0,0.0);
- PSrlineto(0.0,5.0);
- PSrlineto(50.0,0.0);
- PSrlineto(5.0,5.0);
-
- PSrlineto(40.0,0.0);
- PSrlineto(5.0,-5.0);
-
- PSrlineto(80.0,0.0);
- PSrlineto(5.0,5.0);
-
- PSrlineto(40.0,0.0);
- PSrlineto(5.0,5.0);
- PSrlineto(40.0,0.0);
- PSrlineto(5.0,-5.0);
- PSrlineto(40.0,0.0);
- PSrlineto(5.0,-5.0);
- PSrlineto(80.0,0.0);
- PSrlineto(5.0,5.0);
- PSrlineto(40.0,0.0);
- PSrlineto(5.0,-5.0);
- PSrlineto(50.0,0.0);
- PSrlineto(0.0,-5.0);
- PSclosepath();
- PSfill();
- PSflushgraphics();
-
- if( displayBase ) /* display missles base if it has not been destroyed */
- [self drawLaunchPad];
-
- for(i=0;i<CITIES; i++)
- if( cityStatus[i] )
- [self drawCityBM:CBarray[i].coord];
- return self;
- }
-
- - drawCityBM:(NXPoint ) dcPt
- {
- [cityBitmap composite:NX_SOVER toPoint:&dcPt];
- return self;
- }
-
- - drawLaunchPad
- {
- NXPoint Pt;
- Pt.x = 230.0;
- Pt.y = 15.0;
- [launcherBitmap composite:NX_SOVER toPoint:&Pt];
- return self;
-
- }
- - drawMissile
- {
- id missileBitmap = [NXImage findImageNamed:"missileIcon.tiff"];
- NXPoint Pt;
- Pt.x = 160.0;
- Pt.y = 190.0;
- [missileBitmap composite:NX_COPY toPoint:&Pt];
- return self;
- }
-
- - mouseDown:(NXEvent *)theEvent
- {
- NXPoint sPt;
- int pntInRect();
- MSLE_NODE_PNTR mLaunch,p;
-
- sPt = theEvent->location;
- [self convertPoint:&sPt fromView:nil];
-
- if ( defensiveMissiles.launched < MAXDEFLAUNCH && missiles > 0 && pntInRect(&sPt))
- {
- [outMissiles setIntValue:--missiles];
- defensiveMissiles.launched++;
- [self lockFocus];
- markLoc(sPt.x,sPt.y);
- [self unlockFocus];
-
-
- mLaunch = malloc(sizeof(MSLE_NODE));
-
- mLaunch->dPos = sPt;
- mLaunch->cPos.x = LAUNCH_X;
- mLaunch->cPos.y = LAUNCH_Y;
- mLaunch->next = NULL;
-
- // must check for zeros
- if (ABS(sPt.x - LAUNCH_X) > ABS(sPt.y - LAUNCH_Y))
- {
- mLaunch->delta_x = DISP;
- mLaunch->delta_y = DISP *(sPt.y - LAUNCH_Y) /(sPt.x - LAUNCH_X);
- }
- else
- {
- mLaunch->delta_y = DISP;
- mLaunch->delta_x = DISP *(sPt.x - LAUNCH_X)/ (sPt.y - LAUNCH_Y);
- }
-
- if ( defensiveMissiles.next == NULL)
- defensiveMissiles.next = mLaunch;
- else
- {
- p = defensiveMissiles.next;
- while (p->next != NULL )
- p = p->next;
- p->next = mLaunch;
-
- }
- }
-
- return self;
- }
-
- - expDraw
- {
- EXP_PNTR cp,pp;
- pp = cp = defensiveExplosions.next;
- [self lockFocus];
- while (cp != NULL )
- {
- if (cp->rad > MAXRADIUS )
- {
- cp->maxReached = YES;
- cp->rad += ( cp->maxReached ) ? -RADINC: RADINC ;
- pp = cp;
- cp = cp->next;
- }
- else if ( ( cp->rad <= 0.0 ) && cp->maxReached )
- {
- if ( defensiveExplosions.next == cp )
- {
- pp = defensiveExplosions.next = cp->next;
- free(cp);
- cp = pp;
- }
- else
- {
- pp->next = cp->next;
- free(cp);
- cp = pp->next;
- }
- defensiveExplosions.exploding--;
- }
- else
- {
- PSsetgray((cp->maxReached) ? NX_WHITE : NX_BLACK );
- PSarc(cp->cPt.x,cp->cPt.y,cp->rad,0.0,360.0);
- PSstroke();
- PSflushgraphics();
- cp->rad += (( cp->maxReached ) ? -RADINC: RADINC ) ;
- pp = cp;
- cp = cp->next;
- }
- }
- [self unlockFocus];
- return self;
- }
-
- - surfaceExplosionsDraw
- {
- EXP_PNTR cp,pp;
-
- pp = cp = surfaceExplosions.next;
- [self lockFocus];
- while (cp != NULL )
- {
- if (cp->rad > MAXRADIUS )
- {
- cp->maxReached = YES;
- cp->rad += ( cp->maxReached ) ? -RADINC: RADINC ;
- pp = cp;
- cp = cp->next;
- }
- else if ( ( cp->rad <= 0.0 ) && cp->maxReached )
- {
- if ( surfaceExplosions.next == cp )
- {
- pp = surfaceExplosions.next = cp->next;
- PSnewpath();
- PSsetgray( NX_WHITE);
- PSmoveto(cp->cPt.x,cp->cPt.y);
- PSrlineto(-10,0);
- PSrlineto(0,20);
- PSrlineto(30,0);
- PSrlineto(0,-20);
- PSrlineto(-10,0);
- PSfill();
- PSflushgraphics();
- free(cp);
- cp = pp;
- }
- else
- {
- pp->next = cp->next;
-
- PSnewpath();
- PSsetgray( NX_WHITE);
- PSmoveto(cp->cPt.x,cp->cPt.y);
- PSrlineto(-10,0);
- PSrlineto(0,20);
- PSrlineto(30,0);
- PSrlineto(0,-20);
- PSrlineto(-10,0);
- PSfill();
- PSflushgraphics();
-
- free(cp);
- cp = pp->next;
- }
- surfaceExplosions.exploding--;
-
- }
- else
- {
- [self lockFocus];
- PSsetgray((cp->maxReached) ? NX_WHITE : NX_BLACK );
- PSarc(cp->cPt.x,cp->cPt.y,cp->rad,1.0,180.0);
- PSstroke();
- PSflushgraphics();
- [self unlockFocus];
- cp->rad += (( cp->maxReached ) ? -RADINC: RADINC ) ;
- pp = cp;
- cp = cp->next;
-
- }
- }
- [self unlockFocus];
- return self;
-
-
- }
-
-
- - missilePath
- {
- NXPoint nPos; // new missile position
- MSLE_NODE_PNTR cp,pp,dp;
- EXP_PNTR nExp;
-
- pp = cp = defensiveMissiles.next;
- [self lockFocus];
- while ( cp != NULL )
- {
- if ( cp->dPos.y <= cp->cPos.y) /* missile has reached it destination */
- {
- PSmoveto(LAUNCH_X,LAUNCH_Y);
- PSlineto(cp->dPos.x,cp->dPos.y);
- PSsetgray(NX_WHITE);
- PSsetlinewidth(2.0);
- PSstroke();
- PSsetgray(NX_BLACK);
- PSflushgraphics();
-
- if ( cp == defensiveMissiles.next )
- {
- defensiveMissiles.next = cp->next;
- dp = cp;
- cp = defensiveMissiles.next;
- }
- else
- {
- pp->next = cp->next;
- dp = cp;
- cp = pp->next;
- }
- nExp = malloc(sizeof(EXP_NODE));
- nExp->cPt = dp->dPos;
- nExp->rad = 0.0;
- nExp->maxReached = NO;
- nExp->next = NULL;
-
- free(dp);
- [self addToAirExplosions:nExp];
- defensiveMissiles.launched--;
- }
- else /* calculate and plot next position */
- {
-
-
- nPos.x = cp->cPos.x + cp->delta_x;
- if( cp->delta_x < 0 ) /* make sure that point is not past detonation point */
- {
- if( nPos.x < cp->dPos.x)
- nPos.x = cp->dPos.x;
- }
- else
- {
- if( nPos.x > cp->dPos.x )
- nPos.x = cp->dPos.x;
- }
- nPos.y = cp->cPos.y + cp->delta_y;
-
- if ( cp->dPos.y > cp->cPos.y )
- {
- plotTrajectory(cp->cPos.x,cp->cPos.y,nPos.x,nPos.y);
- cp->cPos = nPos;
- }
- pp = cp;
- cp = cp->next;
- }
- }
- [self unlockFocus];
- return self;
- }
-
- - nextLevel
- {
- int cities,i;
-
- cities = 0;
- for(i=0;i<CITIES; i++)
- if( cityStatus[ i ] )
- cities++;
-
- if( cities == 0 )
- gameRunning = FALSE;
- else
- {
- if( phaseOne)
- phaseOne = FALSE;
- else
- {
- phaseOne = TRUE;
- if( dFactor < cdiffmax )
- dFactor += cdiffinc;
- missiles = 40;
- displayBase = TRUE;
- }
- // reset time
- aTimeBefore = currentTimeInMs();
-
-
- [outMissiles setIntValue:missiles];
- [outScore setIntValue:score];
-
- [self display];
-
- // calculate attack positions
- [self selectTargets];
-
- }
- return self;
- }
-
- - bonusPoints
- {
- NXPoint cityPt;
- int cities,i,re;
- int vacantPos[ CITIES ],j;
- unsigned int stime,etime;
-
- cityPt.x = SCOREXPOS;
- cityPt.y = SCOREYPOS;
- cities = 0;
- for(i=0;i<CITIES; i++)
- if( cityStatus[ i ] )
- cities++;
-
- [self lockFocus];
- [self drawCityBM:cityPt];
- [self unlockFocus];
- for(i=0; i <= cities; i++ )
- {
- [self lockFocus];
- scorePhaseCities(i,i*CITYBONUS,&re);
- [self unlockFocus];
- }
-
- etime = stime = currentTimeInMs();
- while( etime - stime < 100 )
- etime = currentTimeInMs();
-
-
- score += cities * CITYBONUS;
- [outScore setIntValue:score];
-
- [self lockFocus];
- [self drawMissile];
- [self unlockFocus];
-
- for(i=0; i <= missiles; i++ )
- {
- [self lockFocus];
- scorePhaseMissiles(i,i*MSLBONUS,&re);
- [self unlockFocus];
-
- etime = stime = currentTimeInMs();
- while( etime - stime < 100 )
- etime = currentTimeInMs();
- }
-
- score += missiles * MSLBONUS;
- [outScore setIntValue:score];
- etime = stime = currentTimeInMs();
- while( etime - stime < 1000 )
- etime = currentTimeInMs();
-
- if( score - lastBonusAt > BONUSMARK )
- {
- lastBonusAt += BONUSMARK;
- j = 0;
- for(i=0;i<CITIES ; i++)
- if( cityStatus[ i ] == FALSE )
- vacantPos[j++] = i; ;
-
- if( j )
- cityStatus[ vacantPos[PLACECITY(j)]] = TRUE;
- else
- score += CITYBONUS;
-
- }
- return self;
- }
-
-
- - selectTargets
- {
- float dx,dy;
- MA_NODE_PNTR head,cp,pp;
- pp = head = cp = malloc(sizeof(MA_NODE));
-
- while (++offensiveMissiles.launched <= MAXATCKMSSLS ) /* attack missles init */
- {
- cp->sPos.x = RANDLAUNCH;
- cp->sPos.y = OLAUNCH_Y;
- cp->targetLoc = RANDTARGET;
- cp->dPos.x = CBarray[cp->targetLoc].coord.x + CDX;
- cp->dPos.y = CBarray[cp->targetLoc].coord.y;
-
- cp->cPos = cp->sPos;
-
- dx = cp->dPos.x - cp->sPos.x ;
- dy = cp->dPos.y - OLAUNCH_Y;
- if ( ABS(dy ) > ABS(dx))
- {
- cp->delta_y = -1.0;
- cp->delta_x = ( dx ) / ABS(dy );
- }
- else
- {
- cp->delta_y = ( dy )/ABS( dx ) ;
- cp->delta_x = ABS(dx ) / dx ;
- }
-
- cp->next = malloc(sizeof(MA_NODE));
- pp = cp;
- cp = cp->next;
-
- }
- offensiveMissiles.launched--;
- offensiveMissiles.next = head;
- pp->next = NULL;
- free(cp);
- [redAlertSound play];
-
- return self;
- }
-
- - addToAirExplosions: (EXP_PNTR )aExp
- {
- EXP_PNTR ep;
-
- if ( defensiveExplosions.next == NULL )
- defensiveExplosions.next = aExp;
- else
- {
- ep = defensiveExplosions.next;
- while (ep->next != NULL )
- ep = ep->next;
- ep->next = aExp;
- }
- defensiveExplosions.exploding++;
- return self;
- }
-
- - addToSurfaceExplosions:(EXP_PNTR) aExp
- {
- EXP_PNTR ep;
-
- if ( surfaceExplosions.next == NULL )
- surfaceExplosions.next = aExp;
- else
- {
- ep = surfaceExplosions.next;
- while (ep->next != NULL )
- ep = ep->next;
- ep->next = aExp;
- }
- surfaceExplosions.exploding++;
- return self;
- }
-
-
- - attackMissilesPath
- {
- MA_NODE_PNTR head,cp,pp;
- EXP_PNTR nExp;
- NXPoint nPt;
- NXRect rect = {{0.0, 0.0}, {1.0, 1.0}};
- id image;
- NXColor colorAtSomeLoc, colorAt();
- float alpha,color;
-
- [self lockFocus];
- head = cp = pp = offensiveMissiles.next; /* set up pointers to point at head of attack missile list */
- while ( cp != NULL )
- {
- // calculate next point in trajectory
- nPt.x = cp->cPos.x + dFactor * cp->delta_x;
- nPt.y = cp->cPos.y + dFactor * cp->delta_y;
-
- // set rect to check if missile has been hit
- rect.origin = nPt;
- image = [[NXBitmapImageRep alloc] initData:NULL fromRect:&rect];
- colorAtSomeLoc = colorAt(image, 0, 0);
- [image free];
-
- NXConvertColorToGrayAlpha (colorAtSomeLoc, &color, &alpha);
- if ( nPt.y < cp->dPos.y) /* attack missile has arrived at target */
- {
- offensiveMissiles.launched--;
- if ( cp->targetLoc == ( TARGETS - 1 ) )
- {
- missiles = 0;
- [outMissiles setIntValue:missiles];
- displayBase = FALSE;
- }
- else
- cityStatus[ cp->targetLoc ] = FALSE;
- /* erase missile trajectory */
- PSmoveto(cp->cPos.x,cp->cPos.y);
- PSlineto(cp->sPos.x,cp->sPos.y);
- PSsetgray(NX_WHITE);
- PSsetlinewidth(2.0);
- PSstroke();
- PSsetlinewidth(1.0);
- PSflushgraphics();
-
- /* creat an explosion node for surface explosions */
- nExp = malloc(sizeof(EXP_NODE));
- nExp->cPt = cp->cPos;
- nExp->rad = 0.0;
- nExp->maxReached = NO;
- nExp->next = NULL;
-
- [self addToSurfaceExplosions:nExp]; /* add explosion to surface exp. list */
-
- if ( cp == head )
- {
- offensiveMissiles.next = head = cp->next;
- free(cp);
- cp = head;
- }
- else
- {
- pp-> next = cp->next;
- free(cp);
- cp = pp->next;
- }
-
- }
- else if ( ( ABS(color - NX_BLACK) < 0.005 ) && ( cp->cPos.y > 35 ))
- {
- offensiveMissiles.launched--; // missile has been destroyed
- score += MSLDSTRCT;
- [outScore setIntValue:score];
- // remove missile trajectory
- PSmoveto(cp->cPos.x,cp->cPos.y);
- PSlineto(cp->sPos.x,cp->sPos.y);
- PSsetgray(NX_WHITE);
- PSsetlinewidth(2.0);
- PSstroke();
- PSsetlinewidth(1.0);
- PSflushgraphics();
-
- nExp = malloc(sizeof(EXP_NODE));
- nExp->cPt = cp->cPos;
- nExp->rad = 0.0;
- nExp->maxReached = NO;
- nExp->next = NULL;
- [self addToAirExplosions:nExp];
-
- // remove missile from list
- if ( cp == head )
- {
- offensiveMissiles.next = head = cp->next;
- free(cp);
- cp = pp = head;
- }
- else
- {
- pp-> next = cp->next;
- free(cp);
- cp = pp->next;
- }
- }
- else
- {
- plotTrajectory(cp->cPos.x,cp->cPos.y,nPt.x,nPt.y);
- cp->cPos = nPt;
- pp = cp;
- cp = cp->next;
- }
- }
- [self unlockFocus];
-
- return self;
- }
-
- int pntInRect(pnt)
- NXPoint *pnt;
- {
- if( pnt->x >= X_TRG && pnt->y >= Y_TRG && pnt->x <= W_TRG && pnt->y <= H_TRG )
- return(TRUE);
- else
- return(FALSE);
- }
-
- void stepFun (DPSTimedEntry timedE, double timeN, void *data)
- {
- [(id)data step ];
- }
-
-
-
- /**************************************************************************************************/
- /* all the following code has been copied from the NeXT answers code provided by NeXT */
- /***************************************************************************************************/
-
- /* Returns the color at a certain pixel location in a bitmap. */
- /* This version assumes the bitmap is 1, 2, 4, or 8 bps deep */
- /* and its either grayscale or RGB. */
-
- NXColor colorAt(NXBitmapImageRep *image, int x, int y)
- {
- int sampleCnt, bps, spp, amask;
- unsigned char *planes[5], data[5];
- NXColorSpace colorSpace;
-
- spp = [image samplesPerPixel];
- bps = [image bitsPerSample];
- colorSpace = [image colorSpace];
-
- #ifdef CHECK_VALIDITY
- if ((bps != 1 && bps != 2 && bps != 4 && bps != 8) ||
- (colorSpace != NX_RGBColorSpace ||
- colorSpace != NX_OneIsBlackColorSpace ||
- colorSpace != NX_OneIsWhiteColorSpace))
- {
- NXLogError ("colorAt() can't deal with provided image.\n");
- return NX_COLORCLEAR;
- }
- #endif
- #ifdef CHECK_RANGE
- if ((x < 0) || (y < 0) || (x >= [image pixelsWide]) ||
- (y >= [image pixelsHigh]))
- {
- NXLogError ("Pixel out of bounds in colorAt().\n");
- return NX_COLORCLEAR;
- }
- #endif
-
- [image getDataPlanes:planes];
-
- amask = (1 << bps) - 1; /* 1, 3, 15, 255 for bps = 1, 2, 4, 8 */
-
- /* Get the samples into the data[] array. */
- if ([image isPlanar])
- {
- int pixel = x * bps;
- int byteLoc = [image bytesPerRow] * y + (pixel >> 3);
- int bitLoc = pixel & 7;
- for (sampleCnt = 0; sampleCnt < spp; sampleCnt++)
- {
- data[sampleCnt] =
- ((*(planes[sampleCnt]+byteLoc)) >> (8 - bitLoc - bps)) & amask;
- }
- }
- else
- {
- unsigned char *byteLoc = planes[0] + [image bytesPerRow] * y;
- int bitLoc = x * bps * spp;
- for (sampleCnt = 0; sampleCnt < spp; sampleCnt++)
- {
- data[sampleCnt] =
- ((byteLoc[bitLoc >> 3]) >> (8 - (bitLoc & 7) - bps)) & amask;
- bitLoc += bps;
- }
- }
-
- /* If no alpha, set it to opaque and increment spp. */
- /* Otherwise, compute the true color values (by un-premultipling). */
-
- if (![image hasAlpha])
- {
- data[spp] = amask;
- spp++;
- }
- else if (data[spp - 1] && data[spp - 1] != amask)
- {
- for (sampleCnt = 0; sampleCnt < spp - 1; sampleCnt++)
- {
- data[sampleCnt] =
- (unsigned char)(0.5 + amask *
- ( ((float)(data[sampleCnt])) / (data[spp - 1]) ));
- }
- }
-
- /* At this point data[] contains spp samples, right justified */
- /* within the range 0..amask. We can either return those, or */
- /* return them in a normalized fashion (in the range 0..255, */
- /* after shifting them over to the left by multiplying them by */
- /* 255/amask), or we can return an NXColor. The latter is less */
- /* efficient, probably, but most abstract. */
-
- switch (colorSpace)
- {
- case NX_RGBColorSpace:
- return NXConvertRGBAToColor(((float)data[0]) / amask,
- ((float)data[1]) / amask,
- ((float)data[2]) / amask,
- [image hasAlpha] ? ((float)data[3]) / amask : NX_NOALPHA);
-
- case NX_OneIsWhiteColorSpace:
- return NXConvertGrayAlphaToColor(((float)data[0]) / amask,
- [image hasAlpha] ? ((float)data[1]) / amask : NX_NOALPHA);
-
- case NX_OneIsBlackColorSpace:
- return NXConvertGrayAlphaToColor(((float)(amask - data[0])) / amask,
- [image hasAlpha] ? ((float)(amask - data[1])) / amask :
- NX_NOALPHA);
- }
- }
-
-
- @end
-